From 0f60ff7a3bbc10ff56b5c00498f16206ade50fe9 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 29 Mar 2006 15:39:22 +0100 Subject: [PATCH] Ensure curr_vcpu in domain.c is set correctly, even when nr physical cpus is greater than max virtual cpus per domain. Also do not initialise secondary CPU smp_processor_id() from smpboot.c cpucount. It will be wrong if some CPUs fail to boot. Signed-off-by: Keir Fraser --- xen/arch/x86/domain.c | 16 +++++++--------- xen/arch/x86/setup.c | 1 + xen/arch/x86/smpboot.c | 9 ++++++--- xen/include/asm-x86/current.h | 2 ++ 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 025c76759e..b8e6ce9708 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -208,6 +208,11 @@ void dump_pageframe_info(struct domain *d) } } +void set_current_execstate(struct vcpu *v) +{ + percpu_ctxt[smp_processor_id()].curr_vcpu = v; +} + struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) { struct vcpu *v; @@ -219,15 +224,8 @@ struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) v->arch.flags = TF_kernel_mode; - if ( is_idle_domain(d) ) - { - percpu_ctxt[vcpu_id].curr_vcpu = v; - v->arch.schedule_tail = continue_idle_domain; - } - else - { - v->arch.schedule_tail = continue_nonidle_domain; - } + v->arch.schedule_tail = is_idle_domain(d) ? + continue_idle_domain : continue_nonidle_domain; v->arch.ctxt_switch_from = paravirt_ctxt_switch_from; v->arch.ctxt_switch_to = paravirt_ctxt_switch_to; diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index b5b0fd68e0..88e667b1ec 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -404,6 +404,7 @@ void __init __start_xen(multiboot_info_t *mbi) BUG_ON(idle_domain == NULL); set_current(idle_domain->vcpu[0]); + set_current_execstate(idle_domain->vcpu[0]); idle_vcpu[0] = current; paging_init(); diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 498c2b5ba2..3a35ca339e 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -441,7 +441,7 @@ void __devinit smp_callin(void) calibrate_tsc_ap(); } -static int cpucount; +static int cpucount, booting_cpu; /* representing cpus for which sibling maps can be computed */ static cpumask_t cpu_sibling_setup_map; @@ -524,12 +524,13 @@ void __devinit start_secondary(void *unused) * booting is too fragile that we want to limit the * things done here to the most necessary things. */ - unsigned int cpu = cpucount; + unsigned int cpu = booting_cpu; extern void percpu_traps_init(void); - set_current(idle_vcpu[cpu]); set_processor_id(cpu); + set_current(idle_vcpu[cpu]); + set_current_execstate(idle_vcpu[cpu]); percpu_traps_init(); @@ -890,6 +891,8 @@ static int __devinit do_boot_cpu(int apicid, int cpu) ++cpucount; + booting_cpu = cpu; + if ((vcpu_id = cpu % MAX_VIRT_CPUS) == 0) { d = domain_create(IDLE_DOMAIN_ID, cpu); BUG_ON(d == NULL); diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h index 2a63b75002..5803141f2a 100644 --- a/xen/include/asm-x86/current.h +++ b/xen/include/asm-x86/current.h @@ -53,4 +53,6 @@ static inline struct cpu_info *get_cpu_info(void) #define schedule_tail(_ed) (((_ed)->arch.schedule_tail)(_ed)) +extern void set_current_execstate(struct vcpu *v); + #endif /* __X86_CURRENT_H__ */ -- 2.30.2